/**
Nectarine Utility Project is a software interface for the web system 'demovibes'
Copyright (C) 2010  Alexandre LAURENT

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

website: http://code.google.com/p/nectarine-utility-project/
e-mail: lw.demoscene@gmail.com
**/

#include "compilation.h"

#include <QString>
#include <QUrl>

#include <QByteArray>
#include <QXmlStreamReader>

#include <QDebug>

#include "../Types/user.h"
#include "../Types/artist.h"
#include "../Types/song.h"

#include "../utils.h"

QDebug operator<<(QDebug dbg, const Compilation& c)
{
    dbg << "Compilation (";
    dbg << "\tID: " << c.id << "\n";
    dbg << "\tTitle: " << c.title << "\n";
    dbg << "\tStatus: " << statusToString(c.status) << "\n";
    dbg << "\tLabel: " << c.label << "\n";
    dbg << "\tMedia type: " << c.mediaType << "\n";
    dbg << "\tSource link: " << c.sourcePage << "\n";
    dbg << "\tPurchase link: " << c.purchaseLink << "\n";
    dbg << "\tDownload link: " << c.downloadLink << "\n";
    dbg << "\tLength: " << c.runningTime << "\n";
    dbg << "\tInfo: " << c.info << "\n";
    dbg << "\tNotes: " << c.notes << "\n";
    dbg << "\tDate of upload: " << c.uploadDate << "\n";
    dbg << "\tUploader: " << c.uploader << "\n";
    dbg << "\tArtists: " << c.artists << "\n";
    dbg << "\tGroups: " << c.groups << "\n";
    dbg << "\tSong: " << c.songs << "\n";
    dbg << ")";

    return dbg.space();
}

bool parseCompilationPage(QXmlStreamReader& xmlReader, Compilation& c)
{
    QXmlStreamReader::TokenType nodeType = xmlReader.tokenType();
    bool isOk = true;

    qDebug() << "parseCompilationPage";

    while ( (nodeType != QXmlStreamReader::EndElement || xmlReader.name() != "comp") && isOk )
    {
        if ( nodeType == QXmlStreamReader::StartElement )
        {
            if ( xmlReader.name() == "comp" )
            {
                c.id = xmlReader.attributes().value("id").toString().toUInt();
            }
            else if ( xmlReader.name() == "title" )
            {
                isOk &= Utils::getXMLStringData(xmlReader,c.title);
            }
            else if ( xmlReader.name() == "status" )
            {
                QString statusString;
                isOk &= Utils::getXMLStringData(xmlReader,statusString);
                if ( isOk )
                {
                    c.status = statusFactory(statusString);
                }
            }
            else if ( xmlReader.name() == "label" )
            {
                isOk &= Utils::getXMLStringData(xmlReader,c.label);
            }
            else if ( xmlReader.name() == "details_link" )
            {
                QString sourceString;
                isOk &= Utils::getXMLStringData(xmlReader,sourceString);
                if ( isOk )
                {
                    c.sourcePage = QUrl(sourceString);
                }
            }
            else if ( xmlReader.name() == "download_link" )
            {
                QString downloadString;
                isOk &= Utils :: getXMLStringData(xmlReader,downloadString);
                if ( isOk )
                {
                    c.downloadLink = QUrl(downloadString);
                }
            }
            else if ( xmlReader.name() == "purchase_link" )
            {
                QString purchaseString;
                isOk &= Utils :: getXMLStringData(xmlReader,purchaseString);
                if ( isOk )
                {
                    c.downloadLink = QUrl(purchaseString);
                }
            }
            else if ( xmlReader.name() == "running_time" )
            {
                QString runningTimeString;
                isOk &= Utils :: getXMLStringData(xmlReader,runningTimeString);
                if ( isOk )
                {
                    unsigned int runningTime = runningTimeString.toUInt(&isOk);
                    if ( isOk )
                    {
                        c.runningTime = QTime(runningTime/3600, runningTime/60, runningTime%60);
                    }
                }
            }
            else if ( xmlReader.name() == "media_format" )
            {
                isOk &= Utils::getXMLStringData(xmlReader,c.mediaType);
            }
            else if ( xmlReader.name() == "prod_artists" )
            {
                while ( (nodeType != QXmlStreamReader::EndElement || xmlReader.name() != "prod_artists") && isOk )
                {
                    if ( nodeType == QXmlStreamReader::StartElement && xmlReader.name() == "artist" )
                    {
                        Artist a;
                        isOk &= parseArtist(xmlReader,a);
                        c.artists.push_back(a);
                    }

                    nodeType = xmlReader.readNext();
                }
            }
            else if ( xmlReader.name() == "prog_groups")    // ToDo: Need check ... was supposed like this
            {
                while ( (nodeType != QXmlStreamReader::EndElement || xmlReader.name() != "prog_groups") && isOk )
                {
                    if ( nodeType == QXmlStreamReader::StartElement && xmlReader.name() == "group" )
                    {
                        Group g;
                        isOk &= parseGroup(xmlReader,g);
                        c.groups.push_back(g);
                    }

                    nodeType = xmlReader.readNext();
                }
            }
            else if ( xmlReader.name() == "prod_songs")
            {
                while ( (nodeType != QXmlStreamReader::EndElement || xmlReader.name() != "prod_songs") && isOk )
                {
                    if ( nodeType == QXmlStreamReader::StartElement && xmlReader.name() == "song" )
                    {
                        Song s;
                        isOk &= parseSongPage(xmlReader,s);
                        c.songs.push_back(s);
                    }

                    nodeType = xmlReader.readNext();
                }
            }
            else if ( xmlReader.name() == "info" )
            {
                isOk &= Utils::getXMLStringData(xmlReader,c.info);
            }
            else if ( xmlReader.name() == "production_notes" )
            {
                isOk &= Utils::getXMLStringData(xmlReader,c.notes);
            }
            else if ( xmlReader.name() == "created_by" )
            {
                QString uploadDate = xmlReader.attributes().value("date").toString();

                c.uploader.id = xmlReader.attributes().value("id").toString().toUInt();

                // We have to parse manually the month because the XML is always in English, but Qt has a localized parser
                c.uploadDate = QDate::fromString(uploadDate.right(uploadDate.length() - uploadDate.indexOf(' ')), " dd, yyyy");
                c.uploadDate.setYMD(c.uploadDate.year(),Utils::unlocalizedMonthFromString(uploadDate),c.uploadDate.day());

                isOk &= Utils::getXMLStringData(xmlReader,c.uploader.name);
            }
            else
            {
                qDebug() << "One tag is not parsed at all -> " << xmlReader.name();
            }
        }

        nodeType = xmlReader.readNext();
    }

    qDebug() << c;

    return isOk;
}

bool readCompilationPage(const QByteArray& streamData, Compilation& c)
{
    QXmlStreamReader xmlReader(streamData);
    QXmlStreamReader::TokenType nodeType;
    bool isOk = true;

    qDebug() << "Parser :: readCompilationPage";

    while ( !xmlReader.atEnd() )
    {
        nodeType = xmlReader.readNext();

        if ( nodeType == QXmlStreamReader::StartElement && xmlReader.name() == "comp" )
        {
            isOk &= parseCompilationPage(xmlReader,c);
        }
    }

    return isOk;
}
